package dgirard.radar;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

public class Radar extends Activity {
	private static final int ANDROID_GREEN = 0xFF97c03d;
	private static final String TAG = "MediaPlayerDemo";
	private MediaPlayer mMediaPlayer;
	private static final int LOCAL_AUDIO = 1;
	private List<RadarPosition> radars = new ArrayList<RadarPosition>();
	public static HashMap<String, Location> friendLocations = new HashMap<String, Location>();

	double valueLon = 2.06102;
	double valueLat = 48.81464;

	private LocationManager locManager;

	final Handler mHandler = new Handler();

	static final private int MENU_ITEM_MAP = Menu.FIRST;
	static final private int MENU_ITEM_REFRESH = Menu.FIRST + 1;

	private int isSoundPlayed = 0;
	protected int warningDistance = 500;

	public long timeLastComputeListRadars = 0;

	public void onCreate(Bundle icicle) {
		//TODO : Create Database in case not exists in the SD Card.
		
		super.onCreate(icicle);
		locManager = (LocationManager) getSystemService(LOCATION_SERVICE);
		final TextView alert = new TextView(this);
		final TextView[] infoRadars = new TextView[10];
		Button btnUpdate = new Button(this);

		btnUpdate.setText("Avertir");
		btnUpdate.setTextSize(70f);

		for (int i = 0; i < infoRadars.length; i++) {
			infoRadars[i] = new TextView(this);
			infoRadars[i].setTextColor(Color.BLACK);
			infoRadars[i].setGravity(Gravity.CENTER);
		}

		alert.setTextSize(90f);
		alert.setTextColor(Color.BLACK);
		alert.setGravity(Gravity.CENTER);

		LinearLayout layout = buildLayout(alert, btnUpdate, infoRadars);
		layout.setBackgroundColor(ANDROID_GREEN);


		setContentView(layout);
		computeListRadars();
		createTimer(layout, alert, infoRadars);

	}

	private void computeListRadars() {
		//TODO : Replace loading from csv by loading from Database...
		
		timeLastComputeListRadars = System.currentTimeMillis();
		try {
			radars.clear();
			InputStream is = getAssets().open("france.csv");
			Log.i(TAG, "Radar : Open");

			int size = is.available();

			// Read the entire asset into a local byte buffer.
			byte[] buffer = new byte[size];
			is.read(buffer);
			is.close();
			Log.i(TAG, "Radar : Read");

			// Convert the buffer into a string.
			String text = new String(buffer);
			Log.i(TAG, "<Radar : Split");
			String[] lignes = text.split("\n");
			Log.i(TAG, "Radar : Split>");

			android.location.Location loc = locManager
					.getLastKnownLocation(LocationManager.GPS_PROVIDER);
			Log.i(TAG, "Radar : Location");

			if (loc != null) {
				createGPSListener();

				float results[] = new float[2];
				for (int i = 0; i < lignes.length; i++) {

					String[] columns = lignes[i].split(";");

					double longitude = new Double(columns[2]);
					double latitude = new Double(columns[3]);
					Location.distanceBetween(loc.getLatitude(), loc
							.getLongitude(), latitude, longitude, results);
					if ((results[0] < 100000)) {
						Log.i(TAG, "" + results[0]);
						RadarPosition radarPosition = new RadarPosition();
						radarPosition.setLongitude(longitude);
						radarPosition.setLatitude(latitude);
						radarPosition.setDepartement(columns[4]);
						radarPosition.setCommune(columns[5]);
						radarPosition.setRoute(columns[6]);
						radars.add(radarPosition);
					}
				}
			}
			Log.i(TAG, "Demarrage");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private void createTimer(final LinearLayout layout, final TextView alert,
			final TextView[] infoRadars) {
		final Runnable mUpdateResults = new Runnable() {
			public void run() {
				getCoordonnates(layout, alert, infoRadars);
			}
		};

		TimerTask task = new TimerTask() {
			@Override
			public void run() {

				mHandler.post(mUpdateResults);
			}
		};

		Timer timer = new Timer();

		timer.schedule(task, 5000, 2000);
	}

	private void createGPSListener() {
		Criteria criteria = new Criteria();
		criteria.setAccuracy(Criteria.ACCURACY_FINE);
		criteria.setAltitudeRequired(false);
		criteria.setBearingRequired(false);
		criteria.setCostAllowed(true);
		criteria.setPowerRequirement(Criteria.POWER_LOW);

		final LocationListener locationListener = new LocationListener() {
			public void onLocationChanged(Location location) {

			}

			public void onProviderDisabled(String provider) {
			}

			public void onProviderEnabled(String provider) {
			}

			public void onStatusChanged(String provider, int status,
					Bundle extras) {
			}
		};

		String provider = locManager.getBestProvider(criteria, true);
		if (provider!=null) {
			locManager.requestLocationUpdates(provider, 3000, // 1min
					100, // 1km
					locationListener);			
		}
	}

	private LinearLayout buildLayout(final TextView alert, Button btnUpdate,
			final TextView[] infoRadars) {
		final LinearLayout mainLayout = new LinearLayout(this);
		SpeedSelector speedSelector = new SpeedSelector(this);

		alert.setText("Ok");

		btnUpdate.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				getCoordonnates(mainLayout, alert, infoRadars);
			}
		});

		speedSelector.setSpeedSelectorListener(new SpeedSelectorListener() {
			public void onSpeedChange(int newSpeed) {
				warningDistance = newSpeed * 1000 * 20 / 3600;
			}
		});

		mainLayout.setOrientation(LinearLayout.VERTICAL);
		mainLayout.addView(alert);
		mainLayout.addView(btnUpdate);

		LinearLayout infoRadarsLayout = new LinearLayout(this);
		infoRadarsLayout.setOrientation(LinearLayout.VERTICAL);
		for (int i = 0; i < infoRadars.length; i++) {
			infoRadarsLayout.addView(infoRadars[i]);
			infoRadars[i].setVisibility(View.VISIBLE);
			infoRadars[i].setText("" + i);
		}

		LinearLayout footLayout = new LinearLayout(this);
		footLayout.addView(speedSelector);
		footLayout.addView(infoRadarsLayout);
		footLayout.setVisibility(View.VISIBLE);

		mainLayout.addView(footLayout);

		btnUpdate.setVisibility(View.VISIBLE);
		alert.setVisibility(View.VISIBLE);
		return mainLayout;
	}

	private void getCoordonnates(LinearLayout layout, TextView alert,
			TextView[] infoRadars) {
		android.location.Location loc = locManager
				.getLastKnownLocation(LocationManager.GPS_PROVIDER);

		if (loc != null) {
			
			if(radars.size()<1){
				computeListRadars();
			}
			
			
			double latitude = loc.getLatitude();
			double longitude = loc.getLongitude();
			float results[] = new float[2];

			float minDistance = 100000f;

			for (Iterator iterator = radars.iterator(); iterator.hasNext();) {
				RadarPosition radarPosition = (RadarPosition) iterator.next();

				Location.distanceBetween(radarPosition.getLatitude(),
						radarPosition.getLongitude(), latitude, longitude,
						results);
				radarPosition.setDistance(Math.floor(results[0]));

				if (results[0] < minDistance)
					minDistance = (float) Math.floor(results[0]);
			}

			if (minDistance < warningDistance) {
				if (isSoundPlayed < 3) {
					playAudio(LOCAL_AUDIO);
				}
				alert.setText("" + (int) minDistance);
				layout.setBackgroundColor(Color.RED);
			} else {
				alert.setText("" + (int) minDistance);
				layout.setBackgroundColor(ANDROID_GREEN);
				isSoundPlayed = 0;
				if (System.currentTimeMillis() - timeLastComputeListRadars > 1000 * 60 * 10) {
					computeListRadars();
				}

			}

			Collections.sort(radars, RadarPositionComparator.getComparator());
			int i = 0;
			friendLocations.clear();
			for (Iterator<RadarPosition> iterator = radars.iterator(); iterator
					.hasNext()
					&& i < 10; i++) {
				RadarPosition radarPosition = (RadarPosition) iterator.next();
				String spannableString = new String("" + radarPosition.commune
						+ radarPosition.departement + radarPosition.route + " "
						+ radarPosition.distance);
				infoRadars[i].setText(spannableString);
				Location friendLocation = new Location("me");
				friendLocation.setLatitude(radarPosition.getLatitude());
				friendLocation.setLongitude(radarPosition.getLongitude());

				friendLocations.put(radarPosition.commune, friendLocation);
			}
		}
	}

	private void playAudio(Integer media) {
		try {
			if ((mMediaPlayer == null) || (!mMediaPlayer.isPlaying())) {

				mMediaPlayer = MediaPlayer.create(this, R.raw.gong);
				mMediaPlayer.start();
				isSoundPlayed++;
			}
		} catch (Exception e) {
			Log.e(TAG, "error: " + e.getMessage(), e);
		}

	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		if (mMediaPlayer != null) {
			mMediaPlayer.release();
			mMediaPlayer = null;
		}

	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		super.onCreateOptionsMenu(menu);
		menu.add(0, MENU_ITEM_MAP, Menu.NONE, R.string.menu_item_map);
		menu.add(0, MENU_ITEM_REFRESH, Menu.NONE, R.string.menu_item_refresh);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		super.onOptionsItemSelected(item);

		switch (item.getItemId()) {
		// Check for each known menu item
		case (MENU_ITEM_MAP):
			startActivity(new Intent(this, WhereAreMyFriendsMap.class));
			return true;
		case (MENU_ITEM_REFRESH):
			return true;
		}

		// Return false if you have not handled the menu item.
		return false;
	}

}